import { DeviceDTO } from "./dto/DeviceDTO";
import * as net from "net";
import MessagePublisher from "./MessageCenter";
import MessageFactory from "./MessageFactory";
import {Device} from "./DbModel/device.entity";

const deviceList: Array<DeviceProxy> = [];

class DeviceProxy {

  /**
   * ID
   */
  id: number

  name: string

  uuid: string

  host: string

  port: number

  /**
   * 是否自动启动
   */
  autoStartFlag: boolean;

  /**
   * 是否正在运行
   */
  running: boolean = false;

  /**
   * 设备状态
   * 初始状态为空
   * connecting: 连接中 connected: 已连接 end: 端口连接
   */
  status: string = null;

  /**
   * 消息列表
   */
  messageList: Array<string> = [];

  socket: net.Socket;

  connected: boolean = false;

  constructor(dto:Device) {
    this.id = dto.id;
    this.uuid = dto.uuid;
    this.host = dto.host;
    this.port = dto.port;
    this.name = dto.name;
    this.running = true;
    // socket
    this.socket = new net.Socket();
    this.socket.end(()=> {
      this.status = 'end';
    })
    // 与服务器保持联系
    this.contactServer();
  }

  contactServer() {
    try {
      // 设置定时器与服务器保持连接
      setInterval(()=>{
        if (!this.running) {
          return;
        }
        // 检查socket的连接状态
        if (this.status != 'connected') {
          try {
            this.socket.connect(this.port, this.host, ()=> {
              this.status = 'connected';
              this.ping();
              console.log("连接服务器成功");
            });
          }catch(e) {
            console.error(e);
            console.log("连接服务器失败");
          }


        }

      }, 1000);


    }catch(err) {
      console.warn(err);
    }

  }

  ping() {
    this.socket.write(MessageFactory.createPingMessage(this.uuid))
  }

  start() {
    this.running = true;
  }

  shutdown() {
    this.running = false;
  }

  addMessage(message: string) {
    MessagePublisher.publish(message);
    this.messageList.push(message);
  }

}

function findDeviceById(id:number) {
  return deviceList.find(device => device.id === id);
}

function getDeviceDTO(device: DeviceProxy) {
  const deviceDTO: DeviceDTO = new DeviceDTO();
  deviceDTO.id = device.id;
  deviceDTO.name = device.name;
  deviceDTO.uuid = device.uuid;
  deviceDTO.host = device.host;
  deviceDTO.port = device.port;
  deviceDTO.running = device.running;
  return deviceDTO;

}

export default {
  /**
   * 设备列表
   */
  list(): Array<DeviceDTO> {
    return deviceList.map(device => {
      return getDeviceDTO(device);
    })
  },
  start(deviceId: number) {
    const device = deviceList.find(device => device.id === deviceId);
    if (device) {
      device.start();
    }
  },
  shutdown(deviceId: number) {
    const device = deviceList.find(device => device.id === deviceId);
    if (device) {
      device.shutdown();
    }
  },
  del(deviceId: number) {
    const index = deviceList.findIndex(device => device.id === deviceId);
    // 把设备从列表中移除
    deviceList.splice(index, 1);
  },
  getStatus(deviceId:number)  {
    const device = deviceList.find(device => device.id === deviceId);
    if (!device) {
      return 0;
    }
    return device.running ? 1 : 0;
  },
  getDetail(deviceId:number)  {
    const device = deviceList.find(device => device.id === deviceId);
    return getDeviceDTO(device);
  },
  publish(dto: Device) {
      const device = new DeviceProxy(dto);
      if (device.autoStartFlag) {
        device.start();
      }
      deviceList.push(device);
  },
  addMessage(deviceId:number, message: string) {
    const device = findDeviceById(deviceId);
    if (device) {
      device.addMessage(message);
    }
  }
}